/**************************************************************************
Step 1. Include necessary header files such that the stuff your test logic needs is declared. 
Don't forget gtest.h, which declares the testing framework.                                                   
**************************************************************************/
#include "gtest/gtest.h"
#include "include/pf_log.h"
#include "include/pf_internal.h"
#include <fcntl.h>
#include <pthread.h>

char* GetDate(char* datebuf)
{
        time_t timer = time(NULL);
        struct tm nowtimer;

        nowtimer = *localtime(&timer);

        sprintf(datebuf, "%04u%02u%02u",
                nowtimer.tm_year + 1900, nowtimer.tm_mon + 1, nowtimer.tm_mday);

        return datebuf;
}
void* thread_log_error(void* arg)
{
    PF_UNUSED(arg);

    pf_log_error("EEEE_module","%s--%d\n","thread_log_error",12346);
    return NULL;
}
void* thread_log_warn(void* arg)
{
    PF_UNUSED(arg);

    pf_log_warn("EEEE_module","%s--%d\n","thread_log_warn",12346);
    return NULL;
}
void* thread_log_info(void* arg)
{
    PF_UNUSED(arg);

    pf_log_info("EEEE_module","%s--%d\n","thread_log_info",12346);
    return NULL;
}
void* thread_log_debug(void* arg)
{
    PF_UNUSED(arg);

    pf_log_debug("EEEE_module","%s--%d\n","thread_log_debug",12346);
    return NULL;
}
void* thread_log_fatal(void* arg)
{
    PF_UNUSED(arg);

    pf_log_fatal("EEEE_module","%s--%d\n","thread_log_fatal",12346);
    return NULL;
}
void* thread_log_trace(void* arg)
{
    PF_UNUSED(arg);

    pf_log_trace("EEEE_module","%s--%d\n","thread_log_trace",12346);
    return NULL;
}
/**************************************************************************
Step 2. Use test fixture to design your complex cases. 
You can add SetUp() to initialize the test data and 
TearDown() to clear the test data for common usage
Pls remember that when you using test fixture, need to use macro "TEST_F" instead of "TEST"                                                 
**************************************************************************/
class PfLogTest : public testing::Test 
{
    /* This SetUp() will be called before every TEST CASE which is marked by macro "TEST_F" */
    virtual void SetUp() 
    {

    }

    /* This TearDown will be called after every TEST CASE which is marked by macro "TEST_F" */
    virtual void TearDown() 
    {

    }

};

/***************************************************************************
Step 3. Use macro "TEST_F" to start your test case                                      
You can design your test case as the example
***************************************************************************/
TEST_F(PfLogTest, pf_log_init_config)
{
    pf_log_config_t my_log;
    pf_log_init_config(&my_log);

    EXPECT_STREQ(my_log.log_path,"./");
    EXPECT_STREQ(my_log.log_file,"log");
    EXPECT_EQ(my_log.log_level,PF_LOG_TRACE);
    EXPECT_EQ(my_log.time_zone,(uint32_t)8);

    strcpy(my_log.log_path,"/aaa/bb");
    strcpy(my_log.log_file,"logmine");
    my_log.log_level = PF_LOG_INFO;
    my_log.time_zone = (uint32_t)10;

    pf_log_init_config(&my_log);

    EXPECT_STREQ(my_log.log_path,"./");
    EXPECT_STREQ(my_log.log_file,"log");
    EXPECT_EQ(my_log.log_level,PF_LOG_TRACE);
    EXPECT_EQ(my_log.time_zone,(uint32_t)8);
}

TEST_F(PfLogTest, pf_log_init)
{
    pf_log_config_t my_log; 
    pf_log_init_config(&my_log);
    strcpy(my_log.log_path,"/logtest/bb");

    FILE* fp = freopen("./log_err.txt","wb+", stderr); 

    int ret = pf_log_init(&my_log);
    EXPECT_EQ(ret, -2);
    fflush(fp);

    FILE* fp_read = fopen("./log_err.txt","r");
    char read_buf[100+1] = {0};
    if(fgets(read_buf, 100, fp_read) != NULL)
    {
        EXPECT_STREQ(read_buf,"create log path : /logtest/bb error : -13 - Permission denied\n");
    }
    EXPECT_NE(strlen(read_buf),(size_t)0);


    pf_log_config_t my_log1;
    pf_log_init_config(&my_log1);
    my_log1.log_level = PF_LOG_INFO;
    strcpy(my_log1.log_path,"./logtest/bb");
    ret = pf_log_init(&my_log1);
    EXPECT_EQ(ret, 0);

    fclose(fp);
    fclose(fp_read); 
} 

TEST_F(PfLogTest, pf_log_write)
{

    char datebuf[100] = {0};
    char filename[200] = {0};
    char read_buf[100+1] = {0};
    GetDate(datebuf);
    system("rm ./logtest/bb/log*");
    pf_log_write("AAAA_module",__FILE__,__LINE__,PF_LOG_INFO,"%s--%d","aaa",12345);
   
    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);

    while(fgets(read_buf, 100, fp_read) != NULL)
    {
       char* datastr = strstr(read_buf,"aaa--12345");
       EXPECT_NE(datastr,(char*)NULL);

       datastr = strstr(read_buf,__FILE__);
       EXPECT_NE(datastr,(char*)NULL);
       datastr = strstr(read_buf,"INFO");
       EXPECT_NE(datastr,(char*)NULL);

    }
    EXPECT_NE(strlen(read_buf),(size_t)0);
    fclose(fp_read);

    pf_log_write("BBBB_module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",22346);
    fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);

    int i = 0;
    while(fgets(read_buf, 100, fp_read) != NULL)
    {
        i++;
        if(i == 2)
        {
            char* datastr = strstr(read_buf,"aaa--22346");
            EXPECT_NE(datastr,(char*)NULL);
            datastr = strstr(read_buf,__FILE__);
            EXPECT_NE(datastr,(char*)NULL);
            datastr = strstr(read_buf,"ERROR");
            EXPECT_NE(datastr,(char*)NULL);
        }
    }
    EXPECT_EQ(i,2);
    fclose(fp_read);

    char longbuf[1000] ;
    memset(longbuf, 'a',999);
    longbuf[999] = '\0';

    pf_log_write("BBBB_module",__FILE__,__LINE__,PF_LOG_WARN,"%s--%d\n",longbuf,12346);
    fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);

    i = 0;
    char long_read_buf[4096+1];
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,3);
    fclose(fp_read);

    char longlongbuf[4096];
    memset(longlongbuf, 'b',4095);
    longlongbuf[4095] = '\0';

    pf_log_write("CCCC_module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n",longlongbuf,12346);
    fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,3);
    fclose(fp_read);

    pf_log_write("DDDD_module",__FILE__,__LINE__,PF_LOG_TRACE,"%s--%d\n",longlongbuf,12346);
    fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,3);
    fclose(fp_read);


    /*
    int ret = unlink(filename);
    EXPECT_EQ(ret,0);

    pf_log_write("BBBB_module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);

    fp_read = fopen(filename,"r");
    EXPECT_EQ(fp_read,(void*)NULL);
    */

}

TEST_F(PfLogTest, pf_log_trace)
{
    char databuf[100] ;
    memset(databuf,'t',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_trace("TTTT_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,3);
    fclose(fp_read);

}
TEST_F(PfLogTest, pf_log_debug)
{
    char databuf[100] ;
    memset(databuf,'d',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_debug("DDDD_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,3);
    fclose(fp_read);

}
TEST_F(PfLogTest, pf_log_info)
{
    char databuf[100] ;
    memset(databuf,'i',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_info("IIII_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,4);
    fclose(fp_read);

}
TEST_F(PfLogTest, pf_log_warm)
{
    char databuf[100] ;
    memset(databuf,'w',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_warn("WWWW_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,5);
    fclose(fp_read);

}
TEST_F(PfLogTest, pf_log_error)
{
    char databuf[100] ;
    memset(databuf,'e',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_error("EEEE_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,6);
    fclose(fp_read);
}
TEST_F(PfLogTest, pf_log_fatal)
{
    char databuf[100] ;
    memset(databuf,'f',99);
    databuf[99] = '\0';
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);

    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);
    pf_log_fatal("FFFF_module","%s--%d\n",databuf,12346)
    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);
    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,7);
    fclose(fp_read);
}
TEST_F(PfLogTest, pf_log_write_thread)
{
    pthread_t thread[6];
    int temp = 0;
    temp = pthread_create(&thread[0], NULL, thread_log_error, NULL);
    EXPECT_EQ(temp,0);
    temp = pthread_create(&thread[1], NULL, thread_log_warn, NULL);
    EXPECT_EQ(temp,0);
    temp = pthread_create(&thread[2], NULL, thread_log_info, NULL);
    EXPECT_EQ(temp,0);
    temp = pthread_create(&thread[3], NULL, thread_log_debug, NULL);
    EXPECT_EQ(temp,0);
    temp = pthread_create(&thread[4], NULL, thread_log_fatal, NULL);
    EXPECT_EQ(temp,0);
    temp = pthread_create(&thread[5], NULL, thread_log_trace, NULL);
    EXPECT_EQ(temp,0);

    pthread_join(thread[0],NULL);
    pthread_join(thread[1],NULL);
    pthread_join(thread[2],NULL);
    pthread_join(thread[3],NULL);
    pthread_join(thread[4],NULL);
    pthread_join(thread[5],NULL);

    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);
    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);

    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);

    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,11);
    fclose(fp_read);
}
TEST_F(PfLogTest, pf_log_write_final)
{
    char long_read_buf[4096+1];
    char datebuf[9];
    char filename[100];
    GetDate(datebuf);
    sprintf(filename,"./logtest/bb/log_%s.log",datebuf);

    pf_log_write("DDDD_module",__FILE__,__LINE__,110,"%s--%d\n","not correct type log",12346111);

    FILE* fp_read = fopen(filename,"r");
    EXPECT_NE(fp_read,(void*)NULL);

    int i = 0;
    while(fgets(long_read_buf, 4096, fp_read) != NULL)
    {
        i++;
    }
    EXPECT_EQ(i,12);
    fclose(fp_read);

    int ret = unlink(filename);
    EXPECT_EQ(ret,0);

    pf_log_write("BBBB_module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);
    pf_log_write("file delted module",__FILE__,__LINE__,PF_LOG_ERROR,"%s--%d\n","aaa",12346);

    fp_read = fopen(filename,"r");
    EXPECT_EQ(fp_read,(void*)NULL);
    system("rm -r ./logtest");
}
